home *** CD-ROM | disk | FTP | other *** search
- program Scprn;
-
- uses
- SysUtils, WinTypes, WinProcs, Classes, Forms,
- Printers, Dialogs, ScMain;
-
- {$R *.RES}
-
- function DibNumColors(pv: pointer): word;
- {given a pointer to a locked DIB, return the number of palette entries: 0,2,16, or 256}
- var
- Bits: integer;
- lpbi: PBITMAPINFOHEADER;
- lpbc: PBITMAPCOREHEADER;
- begin
- lpbi := PBITMAPINFOHEADER(pv);
- lpbc := PBITMAPCOREHEADER(pv);
- {
- /* With the BITMAPINFO format headers, the size of the palette
- * is in biClrUsed, whereas in the BITMAPCORE - style headers, it
- * is dependent on the bits per pixel ( = 2 raised to the power of
- * bits/pixel).
- */
- }
- if (lpbi^.biSize <> sizeof(TBITMAPCOREHEADER)) then
- begin
- if (lpbi^.biClrUsed <> 0) then
- Result := WORD(lpbi^.biClrUsed);
- Bits := lpbi^.biBitCount;
- end
- else
- begin
- Bits := lpbc^.bcBitCount;
- end;
- Result := (1 shl Bits) and $01ff; {up to 8 bits, 2 ^ Bits - otherwise, 0.}
- end;
-
- function LPBits(lpdib: PBITMAPINFOHEADER): pointer;
- { Given a pointer to a locked DIB, return a pointer to the actual bits (pixels) }
- var
- dwColorTableSize: longint;
- begin
- dwColorTableSize := longint( (DibNumColors(lpdib) * sizeof(TRGBQUAD)));
- lpBits := pointer( longint(lpdib) + lpdib^.biSize + dwColorTableSize);
- end;
-
- procedure PrintDIB( PrinterHandle: HDC; BHandle: HBitmap; UserScaleX, UserScaleY: Single;
- Center: TCenterState; AutoScale: Boolean);
- function GetDibResX(Info: PBitmapInfoHeader): Single;
- begin {DIB-resolution in dpi}
- if (Info^.biXPelsPerMeter>0) and (Info^.biXPelsPerMeter<400000) then
- Result:=Info^.biXPelsPerMeter*25.4/1000 {Resolution in dpi}
- else
- Result:=0; {Resolution =0 or greater than 10000dpi}
- end;
- function GetDibResY(Info: PBitmapInfoHeader): Single;
- begin
- if (Info^.biYPelsPerMeter>0) and (Info^.biYPelsPerMeter<400000) then
- Result:=Info^.biYPelsPerMeter*25.4/1000 {Resolution in dpi}
- else
- Result:=0; {Resolution =0 or greater than 10000dpi}
- end;
- function GetPrnResX( h: HDC ): Single;
- begin {Printerresolution in dpi}
- if (GetDeviceCaps(h, logPixelsX)>0) and (GetDeviceCaps(h, logPixelsX)<10000) then
- Result:=GetDeviceCaps(h, logPixelsX)
- else
- Result:=0;
- end;
- function GetPrnResY( h: HDC ): Single;
- begin {Printerresolution in dpi}
- if (GetDeviceCaps(h, logPixelsY)>0) and (GetDeviceCaps(h, logPixelsY)<10000) then
- Result:=GetDeviceCaps(h, logPixelsY)
- else
- Result:=0;
- end;
- var
- Info: PBitmapInfoHeader;
- i: integer;
- x,y,w,h: longint;
- Offset, PageSize: TPoint;
- ScaleX, ScaleY: Single;
- begin
- Info:=GlobalLock(BHandle);
- if (longint(Info)<>0) then begin
- if (GetPrnResX(PrinterHandle)<>0) and (GetPrnResY(PrinterHandle)<>0) and
- (GetDibResX(Info)<>0) and (GetDibResY(Info)<>0) and AutoScale then
- begin
- ScaleX:=GetPrnResX(PrinterHandle) / GetDibResX(Info);
- ScaleY:=GetPrnResY(PrinterHandle) / GetDibResY(Info);
- end else begin
- ScaleX:=1;
- ScaleY:=1;
- end;
- if (ScaleX>10000) or (ScaleY>10000) or (ScaleX<0.0001) or (ScaleY<0.0001) then
- begin
- ScaleX:=1;
- ScaleY:=1;
- end;
- ScaleX:=UserScaleX*ScaleX;
- ScaleY:=UserScaleY*ScaleY;
- if Escape(PrinterHandle, GETPRINTINGOFFSET, 0, NIL, @Offset)<=0 then
- Offset:=point(0,0);
- { center the destination bitmap }
- {if Escape(Printer.Canvas.Handle, GETPHYSPAGESIZE, 0, NIL, @PageSize)<=0 then}
- PageSize:=point(GetDeviceCaps(PrinterHandle, HORZRES), GetDeviceCaps(PrinterHandle, VERTRES));
- w:=round(Info^.biWidth*ScaleX);
- h:=round(Info^.biHeight*ScaleY);
- case Center of
- tctNone: begin
- X:=0; Y:=0;
- end;
- tctTopCenter: begin
- X:=(PageSize.X-w) div 2;
- Y:=0;
- Offset:=point(0,0);
- end;
- tctCenter: begin
- X:=(PageSize.X-w) div 2;
- Y:=(PageSize.Y-h) div 2;
- Offset:=point(0,0);
- end;
- tctBottomCenter: begin
- X:=(PageSize.X-w) div 2;
- Y:=(PageSize.Y-h);
- Offset.X:=0;
- end;
- else begin
- X:=0; Y:=0;
- end;
- end;
- i:=StretchDIBits( PrinterHandle,
- X-Offset.X, Y-Offset.Y, w, h,
- 0, 0, Info^.biWidth, Info^.biHeight,
- LPBits(Info), PBitmapinfo(Info)^,
- DIB_RGB_COLORS, SRCCOPY);
- end;
- GlobalUnlock(BHandle);
- end;
-
- function SetCopies( count: Integer ): Integer;
- var DevMode: TDevMode;
- PrintDevice, PrintDriver,PrintPort,DriverName: array[0..255] of char;
- PrintDeviceMode: THandle;
- P: PDevMode;
- begin
- Result:=count;
- Printer.GetPrinter(PrintDevice,PrintDriver,PrintPort,PrintDeviceMode);
- if PrintDeviceMode <> 0 then
- begin
- P := Ptr(PrintDeviceMode, 0);
- if (P^.dmFields and DM_COPIES)= DM_COPIES then
- begin
- P^.dmCopies:=count;
- Printer.SetPrinter(PrintDevice,PrintDriver,PrintPort,PrintDeviceMode);
- Printer.GetPrinter(PrintDevice,PrintDriver,PrintPort,PrintDeviceMode);
- if (P^.dmFields and DM_COPIES)= DM_COPIES then
- begin
- {substract the copies that the printer does for me}
- Result:=Count-P^.dmCopies;
- end;
- end;
- end;
- end;
-
- procedure StartPrinting;
- var
- BHandle: HBitmap;
- UserScaleX, UserScaleY: Single;
- Center: TCenterState;
- aScale,aCopies: Boolean;
- i,Count: Integer;
- PSettings: PGlobalSettings;
- Settings: THandle;
- c: array[0..255] of char;
- begin {start printjob from commandline}
- BHandle:=0;
- UserScaleX:=1.0; UserScaleY:=1.0;
- Center:=tctTopCenter;
- aScale:=True;
- if ParamCount=1 then
- begin
- {Application.Messagebox('Params accepted','OK',MB_OK);}
- Settings := StrToInt( ParamStr(1) );
- if Settings<>0 then
- begin
- PSettings:=GlobalLock( Settings );
- if PSettings<>nil then
- begin
- with PSettings^ do
- begin
- BHandle:= BitmapHandle;
- UserScaleX:= ZoomX;
- UserScaleY:= ZoomY;
- Center:= CenterState;
- Count := NoOfCopies;
- aScale := AutoScale;
- aCopies:= PrinterCopies;
- Printer.SetPrinter(PrintDevice,PrintDriver,PrintPort,PrintDeviceMode);
- end;
- end;
- GlobalUnlock( Settings );
- GlobalFree(Settings);
- end;
- if BHandle<>0 then
- begin
- with Printer do begin
- Printer.Title:='ScPrn: '+IntToStr(Settings);
- try
- SetCopies(1);
- if aCopies then
- Count:=SetCopies(Count); {look that the printer does the copies}
- repeat
- BeginDoc;
- PrintDIB(Canvas.Handle, BHandle, UserScaleX, UserScaleY, Center, aScale );
- EndDoc;
- Count:=Count-1;
- until Count<1;
- finally;
- GlobalFree( BHandle );
- end;
- end;
- end;
- end else
- ShowMessage('This program is called from sc.exe. Version 2.0');
- end;
-
- begin
- {wait until previous instance has finished printing}
- while (GetInstanceModule( HPrevInst )<>0) do
- Application.ProcessMessages;
- StartPrinting;
- end.
-